local BaseFrame = class("BaseFrame")
local protocol = require("gamemodel.protocol")
local scheduler = cc.Director:getInstance():getScheduler()
local HERTBREAK_TIME = 2
local HERTBREAK_DELTA_TIME = 8
-- require("net.netlib")

function BaseFrame:ctor(view,callback)
	self._viewFrame = view
	self._threadid  = nil
	--  self._socket    = require("net.qxnetlib")
	--self._socket    = require("net.csocketlib")
	self._socket = CClientSocket:createSocket(self._SocketFun)
	self._callBack = callback
	-- 游戏长连接
	self._gameFrame = nil
	self.m_tabCacheMsg = {}
	self.sendHeartTime = 0
	self._curIpIndex = 1
	self.retryConenctTime = 0
	self._backupList = view:getApp()._serverConfig and view:getApp()._serverConfig.gatelist or {}

	if device.platform == "windows" then

	end


	if appdf.APPSTORE_VERSION then
		self._backupList= {"gasmesa.uztxf.com:28001"}
	end
	local testip = cc.UserDefault:getInstance():getStringForKey("testip") 
	print("testip>>>>>>",testip)
	if testip and testip ~= "" then
		self._backupList= {testip}
		print("use testip")
	end

	-- if not appdf.heartSch then
	-- 	appdf.heartSch = scheduler:scheduleScriptFunc( function() 
	-- 		self:sendHeartbreak() 
	-- 	end ,HERTBREAK_TIME,false);

	-- end
end

function BaseFrame:getSocketStatus()
	return self._socket.netStatus
end

function BaseFrame:setBackupIpList(tbList)
	self._backupList = tbList
end


function BaseFrame:setCallBack(callback)
	self._callBack = callback
end

function BaseFrame:setViewFrame(viewFrame)
	self._viewFrame = viewFrame
end

function BaseFrame:setSocketEvent(socketEvent)
	self._socketEvent = socketEvent	
end

function BaseFrame:getViewFrame()
	return self._viewFrame
end

function BaseFrame:isSocketServer()
	return self._socket ~= nil and self._threadid ~=nil
end

local targetPlatform = cc.Application:getInstance():getTargetPlatform()

--启动网络
function  BaseFrame:connectServer(szUrl,nPort)

	--创建连接
	local this = self
	self._szServerUrl = szUrl or self._backupList[self._curIpIndex]

	local urlTb = string.split(self._szServerUrl,":")
	self._szServerUrl = urlTb[1] or self._szServerUrl
	self._nServerPort = urlTb[2] or 8001
	
	print("connectServer---->",self._szServerUrl,self._nServerPort)
	if not self._socket then
	    print("hxh test3")
		return
	end
	
    self._socket:addEventListener(qxnetlib.EVENT_SERVER_CONNECTED, function()
		self._socket:removeEventListener(qxnetlib.EVENT_SERVER_CONNECTED)
		self.lastPingAck = os.time()
		if not appdf.heartSch then
			appdf.heartSch = scheduler:scheduleScriptFunc( function() 
				self:sendHeartbreak() 
			end ,HERTBREAK_TIME,false);
		end
	end)
	
	self._socket.onRecvBuff = function(wCtrl,wMsgID,recvJson)
		this:onSocketCallBack(wCtrl,wMsgID,recvJson)
	end
	print("connectServer>>>>",self._szServerUrl,self._nServerPort)
	self:startConnectServer()

	self._socket:addEventListener(qxnetlib.EVENT_SOCKET_CLOSED, function()
		if self._viewFrame then
			self._viewFrame:dismissPopWait()
		end
		-- self._socket._onClose()
	end)

	self._socket:addEventListener(qxnetlib.EVENT_TRY_RECONNECTED, function()
		self._viewFrame:showPopWait()
	end)

	self._socket:addEventListener(qxnetlib.EVENT_TRY_C_RECONNECTED, function()
		
		if self._curIpIndex > #self._backupList then
			self._curIpIndex = 1
		end
		self._szServerUrl = self._backupList[self._curIpIndex]
		self._curIpIndex = self._curIpIndex + 1

		local urlTb = string.split(self._szServerUrl,":")
		self._szServerUrl = urlTb[1] or self._szServerUrl
		self._nServerPort = urlTb[2] or 8001


		self._socket._host = self._szServerUrl
		self._socket._port = self._nServerPort
		
		self:startConnectServer()
		if self._viewFrame and self._viewFrame.showPopWait then
			self._viewFrame:showPopWait()
	
		end
	end)
	
end

function BaseFrame:closeHeartBreak( ... )
	if appdf.heartSch then
		scheduler:unscheduleScriptEntry(appdf.heartSch);
	end
	appdf.heartSch = nil
end

function BaseFrame:reConnectServer( )
	-- body
	self._socket._reConnectServer();
end

function BaseFrame:onSendAuth(recvJson)
	local js = {msgid= protocol.CM_CLIENT_AUTH,authcode=recvJson.authcode}
	local jsonstr = cjson.encode(js)
	--self._socket.send(protocol.CTRL_CLIENT_HALL,protocol.CM_CLIENT_AUTH, jsonstr,true)
end

function BaseFrame:pause( ... )
    -- body()
    self._socket._pauseRecv()
    -- qxnetlib._onClose()
end

function BaseFrame:resume( ... )
    -- body()
    self._socket._resumeRecv()
end



--网络消息回调

function BaseFrame:onSocketCallBack(wCtrl,wMsgID,recvJson)
	--无效数据
	if not self._callBack then
		print("base frame no callback")
		self:onCloseSocket()
		return
	end
	-- 连接命令
	print("onSocketCallBack wCtrl:"..wCtrl.."#wMsgID:"..wMsgID)	
	-- dump(recvJson,"recvJson")

	self.lastPingAck = os.time()
	if wMsgID == protocol.SM_CLIENT_AUTH then 		--授权
		self:onSendAuth(recvJson)
	elseif wMsgID == protocol.SM_CLIENT_AUTHACK then 		--授权成功
		if recvJson and recvJson.result ~= 1 then
			showToast(self._viewFrame,recvJson.msg or "登录失败"..tostring(recvJson.result))
			return
		end
		self._socket.authack =  true
		self:onConnectCompeleted()
	-- elseif wMsgID == protocol.SM_PINGACK then   --心跳
	else
		self:onSocketEvent(wCtrl,wMsgID,recvJson)
	end
end

--关闭网络
function BaseFrame:onCloseSocket()

	self._socket.onCloseSocket()

end


--连接OK
function BaseFrame:onConnectCompeleted()
	print("warn BaseFrame-onConnectResult-")
	local account  = self._viewFrame._szAccount
	local pwd  =  self._viewFrame._szPassword 
--	self._viewFrame._szAccount
--	self._viewFrame._szPassword 
	if not appdf.heartSch then
		appdf.heartSch = scheduler:scheduleScriptFunc( function() 
			self:sendHeartbreak() 
		end ,HERTBREAK_TIME,false);

	end
	self.lastPingAck = os.time()
	self.retryConenctTime = 0
	if account and pwd and account ~= "" and pwd ~= "" then
		self:sendLogon(account,pwd)
		return
	end
	if account and not pwd and account == "guest" then
		self:sendVisitor()
		return
	end

	local accountinfo = GlobalUserItem.getAccountInfo()

	if  accountinfo.type == 1 or ( accountinfo.account and accountinfo.account ~= "") then
		self:sendLogon(accountinfo.account,accountinfo.pwd)
	else
		self:sendVisitor(true)
	end
end

function BaseFrame:sendHeartbreak()
	local curts =  os.time()
	print("sendHeartbreak>>>>>>>>",self.lastPingAck,self.checkHeartBreak)
	if self.retryConenctTime  > 3 then
		self:addGateList()
		self._callBack(-1,"网络连接失败，请重试")
		self._viewFrame:dismissPopWait()
		self:logout()
		self.retryConenctTime = 0
		return
	end
	
	self.status = self._socket._doConnect()
	if not self.status then
		-- self._socket._onClose()
		if not self.reconnected then
			self:startConnectServer(true)
			if self._viewFrame and self._viewFrame.showPopWait then
				self._viewFrame:showPopWait()
			end
			self.reconnected =  true
		else
			self.reconnected =  false
			self._socket._reConnectServer()
			self.retryConenctTime = self.retryConenctTime + 1
		end

		self.lastPingAck = curts
		return
	end
	if self.status == self._socket.socket_state_connect_close then
		self:startConnectServer(true)
		return
	end
	self.sendHeartTime = self.sendHeartTime + 1
	if  self.sendHeartTime%2 == 1 then
		return
	end
	if  self.lastPingAck and self.lastPingAck < curts - HERTBREAK_DELTA_TIME then
		self._viewFrame:showPopWait()
		self._socket._onClose()
		self._socket._reConnectServer()
		self.lastPingAck = curts
		self.retryConenctTime = self.retryConenctTime + 1
	else
		self:sendData(protocol.CTRL_CLIENT_HALL,protocol.CM_PING)
	end
	self.checkHeartBreak =  not self.checkHeartBreak
	self.reconnected =  false
end

function BaseFrame:sendData(wCtrl,wMsgid,jsonstr,bfor)
	if not wCtrl or not wMsgid then
		print("ERROR sendData  wCtrl or wMsgid  is nil",wCtrl,wMsgid)
		return
	end
	print("hxh sendData")
	----self._socket.send(wCtrl,wMsgid, jsonstr,bfor)
end


function BaseFrame:sendStructData(wCtrl,wMsgid,jsonstr,bfor)
	if not wCtrl or not wMsgid then
		print("ERROR sendStructData  wCtrl or wMsgid  is nil",wCtrl,wMsgid)
		return
	end
	--self._socket.sendStruct(wCtrl,wMsgid, jsonstr,bfor)
end


function BaseFrame:logout( ... )
	self:sendData(protocol.CTRL_CLIENT_HALL,protocol.CM_LOGOUT)
	self:closeHeartBreak()
	self._socket._onClose()
end

function BaseFrame:sendVisitor(isbaseEntrance)
	self.status = self._socket._doConnect()
	print("sendVisitor>>>>>>>")
	if self.status == self._socket.socket_state_connect_close  then
		self:startConnectServer(true)
		return
	end
	local mulAngents = self._viewFrame:getApp()._serverConfig.mulAngents
	if mulAngents == "1" and isbaseEntrance and self._viewFrame.openlogonview then
		self._viewFrame:openlogonview()
		return
	end
	local js = {msgid=protocol.CM_LOGIN,loginmode=protocol.VISITOR_MODE,ip=appdf.ip,
	machineid=appdf.MachineCode,channelid=appdf.channelId}
	local jsonstr = cjson.encode(js)
	print("sendVisitor>>>>>>>",jsonstr)
	self:sendData(protocol.CTRL_CLIENT_HALL,protocol.CM_LOGIN, jsonstr)

end

function BaseFrame:sendLogon(_szAccount,_szPassword)
	self.status = self._socket._doConnect()
	if self.status == self._socket.socket_state_connect_close  then
		self:startConnectServer(true)
		return
	end
	
	GlobalUserItem.szAccount = _szAccount
	GlobalUserItem.szPassword = _szPassword
	GlobalUserItem.accounttype = 1

	local js = {msgid=protocol.CM_LOGIN,loginmode=protocol.ACCOUNT_MODE,ip=appdf.ip,
	machineid=appdf.MachineCode,username=_szAccount,password=_szPassword,channelid = appdf.channelId}
	local jsonstr = cjson.encode(js)
	self:sendData(protocol.CTRL_CLIENT_HALL,protocol.CM_LOGIN, jsonstr)

end

function BaseFrame:sendPadLogon(logondata)
	self.status = self._socket._doConnect()
	if self.status == self._socket.socket_state_connect_close  then
		self:startConnectServer(true)
		return
	end
	local js = {msgid=protocol.CM_LOGIN,loginmode=protocol.PAD_MODE,pad_cpid = tonumber(logondata.cpid),
	pad_location = logondata.location,pad_photourl=logondata.photoUrl,
	pad_gametype= tonumber(logondata.gameType),pad_gamekey=logondata.gameKey,ip=appdf.ip,
	pad_uuid=logondata.uuid,pad_imei=logondata.imei,pad_token=logondata.token,pad_gameid = logondata.gameId}
	local jsonstr = cjson.encode(js)
	dump(jsonstr,"sendPadLogon")
	-- self:sendVisitor()
	self:sendData(protocol.CTRL_CLIENT_HALL,protocol.CM_LOGIN, jsonstr)

end


function BaseFrame:onSocketEvent(wCtrl,wMsgID,recvJson)
	print("warn BaseFrame-onSocketData-"..wCtrl.."-"..wMsgID)
	
	if wCtrl == 0 then
		if self.onSocketLoginEvent then
			self:onSocketLoginEvent(wMsgID,recvJson)
		end
		if self.onSocketClientEvent then
			self:onSocketClientEvent(wMsgID,recvJson)
		end
	elseif self.onSocketGameEvent then
		self:onSocketGameEvent(wMsgID,recvJson)
	end
end

--网络消息(长连接)
function BaseFrame:onGameSocketEvent(main,sub,pData)
	print("warn BaseFrame-onGameSocketEvent-"..main.."-"..sub)
end

local function checkMsg(msg)
	if not msg or type(msg) ~= 'table' then
		return false
	end
	return true
end

--绑定银行卡和支付宝信息
function BaseFrame:sendBindMoneyInfo(msg)
	if not checkMsg(msg) then
		return 
	end

	local proId = 0
	local jscontents = ''
	if msg.type == 1 then	--支付宝
		jscontents = {msgid=protocol.CXM_SETALIPAYID,alipayid=msg.bindid,alipayusername=msg.bindname}
		proId = protocol.CXM_SETALIPAYID
	elseif msg.type == 2 then --银行卡
		jscontents = {msgid=protocol.CXM_SETBANKID,bankid=msg.bindid,bankusername= msg.bindname,bankname = msg.bankname,bankaddr=msg.bankaddr}
		proId = protocol.CXM_SETBANKID
	else
		return
	end
	self:sendData(protocol.CTRL_CLIENT_BRICK,proId,cjson.encode(jscontents))
end

--修改昵称
function BaseFrame:sendModifyName(msg)
	if not checkMsg(msg) then
		return 
	end

	local js = {msgid= protocol.CXM_CHANGENICK ,nickname = msg.newname or "霸气的名字2223" }

	self:sendData(protocol.CTRL_CLIENT_BRICK,protocol.CXM_CHANGENICK,cjson.encode(js))
end

--修改头像
function BaseFrame:sendModifyHeadPic(msg)
	if not checkMsg(msg) then
		return 
	end

	local js = { msgid= protocol.CXM_CHANGEFACE,faceid=msg.faceid}
	self:sendData(protocol.CTRL_CLIENT_BRICK,protocol.CXM_CHANGEFACE,cjson.encode(js))
end

function BaseFrame:isConnected()
	
	return self._socket._doConnect();
end

function BaseFrame:startConnectServer(changeurl)
	if changeurl then
		self._curIpIndex = self._curIpIndex + 1
		if self._curIpIndex > #self._backupList then
			self._curIpIndex = 1
		end
		self._szServerUrl = self._backupList[self._curIpIndex]
		local urlTb = string.split(self._szServerUrl,":")
		self._szServerUrl = urlTb[1] or self._szServerUrl
		self._nServerPort = urlTb[2] or 8001
	end
	print("startConnectServer>>>>>>",self._szServerUrl,self._nServerPort,self._curIpIndex)
	-- by djy 疑似处理连接中动画，现在应该是用其他方式处理过了
	-- if self._viewFrame then
	-- 	appdf.PostCustomEvent(yl.EVENT_TRY_CONNECTED,{},self._viewFrame)
	-- end
	self._socket.connectServer(self._szServerUrl,self._nServerPort);
end

function BaseFrame:addGateList()
	print("self._backupList 111  >>>>    ")
	local isConfig = cc.FileUtils:getInstance():isFileExist(device.writablePath.."config.txt")
	if isConfig == true then
		local tempDefaultConfigStr = cc.FileUtils:getInstance():getStringFromFile(device.writablePath.."config.txt");
		local tempConfigData = cjson.decode(tempDefaultConfigStr);
		local tempGateList = tempConfigData.data.gatelist
		dump(tempGateList)
		-- local tempArr = {}
		-- local tempIndex = 1
		-- for i=1,#tempGateList do
		-- 	-- self._backupList[#self._backupList+1] = tempGateList[i]
		-- 	-- table.insert(self._backupList,#self._backupList+1,tempGateList[i])
		-- 	tempArr[tempIndex]=tempGateList[i]
		-- 	tempIndex = tempIndex + 1
		-- end
		-- for j=1,#self._backupList do
		-- 	tempArr[tempIndex]=self._backupList[j]
		-- 	tempIndex = tempIndex + 1
		-- end
		self._backupList = tempGateList
		self._curIpIndex = 1
		self._szServerUrl = self._backupList[self._curIpIndex]
		local urlTb = string.split(self._szServerUrl,":")
		self._szServerUrl = urlTb[1] or self._szServerUrl
		self._nServerPort = urlTb[2] or 8001
	else
		return
	end
	dump(self._backupList)
end

return BaseFrame